local ffi = require('ffi');
local SDL2 = ffi.load('SDL2');
local rectBuffer = ffi.new('SDL_Rect[0x100]');
require('view.lSDL_ttf');

SDL_PIXELFORMAT_YUY2 = 0x32595559
SDL_PIXELFORMAT_BGR565 = 0x15551002
SDL_PIXELFORMAT_RGBA32 = 0x16762004
SDL_PIXELFORMAT_IYUV = 0x56555949
SDL_PIXELFORMAT_INDEX4LSB = 0x12100400
SDL_PIXELFORMAT_RGB24 = 0x17101803
SDL_PIXELFORMAT_BGR888 = 0x16561804
SDL_PIXELFORMAT_BGRA5551 = 0x15841002
SDL_PIXELFORMAT_BGRX8888 = 0x16661804
SDL_PIXELFORMAT_ABGR1555 = 0x15731002
SDL_PIXELFORMAT_INDEX4MSB = 0x12200400
SDL_PIXELFORMAT_BGR555 = 0x15530F02
SDL_PIXELFORMAT_ARGB8888 = 0x16362004
SDL_PIXELFORMAT_BGRA32 = 0x16362004
SDL_PIXELFORMAT_ARGB32 = 0x16862004
SDL_PIXELFORMAT_UYVY = 0x59565955
SDL_PIXELFORMAT_ABGR4444 = 0x15721002
SDL_PIXELFORMAT_BGR24 = 0x17401803
SDL_PIXELFORMAT_YVYU = 0x55595659
SDL_PIXELFORMAT_ABGR8888 = 0x16762004
SDL_PIXELFORMAT_NV12 = 0x3231564E
SDL_PIXELFORMAT_RGB555 = 0x15130F02
SDL_PIXELFORMAT_RGB565 = 0x15151002
SDL_PIXELFORMAT_NV21 = 0x3132564E
SDL_PIXELFORMAT_YV12 = 0x32315659
SDL_PIXELFORMAT_ABGR32 = 0x16462004
SDL_PIXELFORMAT_ARGB2101010 = 0x16372004
SDL_PIXELFORMAT_BGRA8888 = 0x16862004
SDL_PIXELFORMAT_RGBA8888 = 0x16462004
SDL_PIXELFORMAT_RGBX8888 = 0x16261804
SDL_PIXELFORMAT_BGRA4444 = 0x15821002
SDL_PIXELFORMAT_RGBA4444 = 0x15421002
SDL_PIXELFORMAT_ARGB4444 = 0x15321002
SDL_PIXELFORMAT_RGB444 = 0x15120C02
SDL_PIXELFORMAT_RGB332 = 0x14110801
SDL_PIXELFORMAT_INDEX8 = 0x13000801
SDL_PIXELFORMAT_INDEX1MSB = 0x11200100
SDL_PIXELFORMAT_INDEX1LSB = 0x11100100
SDL_PIXELFORMAT_UNKNOWN = 0x0
SDL_PIXELFORMAT_RGB888 = 0x16161804
SDL_PIXELFORMAT_ARGB1555 = 0x15331002
SDL_PIXELFORMAT_RGBA5551 = 0x15441002

local setmeta = function(dst,src)
    for k,v in pairs(src)do
        dst[k] = v;
    end
end

local assertMeta = function(src,dst)
    for k,v in pairs(src)do
        assert(dst[k]~=nil,"错误的类型");
    end
end

local function createTexture(r,w,h)
    local fmt = SDL_PIXELFORMAT_RGBA8888;
    local access = SDL2.SDL_TEXTUREACCESS_TARGET;
    local texture = SDL2.SDL_CreateTexture(r,fmt,access,w,h);
    SDL2.SDL_SetTextureBlendMode(texture,SDL2.SDL_BLENDMODE_BLEND);
    return ffi.gc(texture,SDL2.SDL_DestroyTexture);
end

--
local Memu = {
};

local View = {};
View.__index = View;
function View.new(window)
    local self = {};
    self.renderer = window.renderer;
    self.x = 0;
    self.y = 0;
    self.w = 10;
    self.h = 10;
    return setmetatable(self, View);
end

function View:Render()
    if(self.texture)then
        local rect = rectBuffer;
        rect[0].x = self.x;
        rect[0].y = self.y;
        rect[0].w = self.w;
        rect[0].h = self.h;

        return SDL2.SDL_RenderCopy(self.renderer,self.texture,nil,rect);
    end
end

function View:SetSourceDrawPos(x,y)
    if(self.drawPos==nil)then self.drawPos = {}; end;
    self.drawPos.x = x;
    self.drawPos.y = y;
end

--有关ListView的渲染
local ListView = {};
setmeta(ListView,View)

function ListView.new(window)
    local self = View.new(window);
    return setmetatable(self,ListView);
end

--渲染列表
function ListView:Render()
    View.Render(self);
    if(self.views)then
        for k,v in ipairs(self.views)do
            v:Render();
        end
    end
end

function ListView:Add(view)
    assertMeta(View,view);
    table.insert(self.views,view);
end

local TextListView = {};
setmeta(TextListView,View);
for k,v in pairs(TextListView)do
    print(k,v);
end
TextListView.__index = TextListView;
function TextListView.new(renderer)
    local self = View.new(renderer);
    self.drawPos = {x = 0,y = 0};
    return setmetatable(self,TextListView);
end

function TextListView:Event(event)
    --鼠标时间
    event = event.motion;
    local x,y = event.x,event.y;
    x = x - self.x;
    y = y - self.y;
    --在控件外
    if(x<0 or x>self.w)then return; end;
    if(y<0 or y>self.h)then return; end;

    if(event.type==0x400)then
        --0x400是移动事件
        if(event.state==1)then
            --左键按压
            self.drawPos.y = self.drawPos.y - event.yrel;
            self.selectY = event.y;
            self.drag = true;
            self.selectItem = nil; 
        end
    elseif(event.type==0x401)then
        --按下事件
        self.timestamp = event.timestamp; --时间戳
        self.selectY = event.y;
        self.drag = nil;
        if(self.OnTouch)then
            self:OnTouch(event);
        end
    elseif(event.type==0x402 and self.selectY)then
        --按键抬起
        self.selectY = nil;
        self.selectItem = nil;
        if(self.timestamp==nil or (event.timestamp-self.timestamp<500))then
            --时间戳500ms
            if(self.drag)then
                --拖动
            elseif(self.OnClick)then
                self:OnClick(event);
            end
            --print("触发点击事件");
        end
        self.drag = nil;
    end
end

function TextListView:OnClick(event)
    local item = self:GetSelectItem(event);
    if(item)then
        if(item.Click)then
            item:Click(self,event);
        end
    end
end

function TextListView:OnTouch(event)
    local item = self:GetSelectItem(event);
    self.selectItem = item;
end

--获得选择项
function TextListView:GetSelectItem(event)
    local x,y = event.x,event.y; --获得当前鼠标坐标
    --获得真实的在纹理上的坐标

    --获得在View在屏幕的坐标
    x = x - self.x;
    y = y - self.y;

    if(x<0 or x>self.w)then
        --x事件在外面
        return nil;
    end
    

    --print(x,y);
    if(false)then
        --不触发事件
        --print(x,y);
    else
        --触发事件
        --暂时遍历循环.
        --如果遇到数据比较多的时候,会修改成二叉树查询
        local text;
        local index = 0;
        for k,v in ipairs(self.texts)do
            if(v.y<y and v.y+v.h>y)then
                text = v;
                index = k;
                break;
            elseif(v.y>y)then
                break;
            end
        end

        -- if(text)then
        --     if(text.Click)then
        --         text:Click(self);
        --     end
        -- end
        return text;
    end
    --print("pos:",x,y);
end

function TextListView:Render()
    local target;
    if(self.texture==nil and self.x and self.y and self.w and self.h)then
        local x,y,w,h = self.x,self.y,self.w,self.h;
        self.texture = createTexture(self.renderer,w,h);
    end
    if(self.texture)then
        target = SDL2.SDL_GetRenderTarget(self.renderer);
        SDL2.SDL_SetRenderTarget(self.renderer,self.texture);
        SDL2.SDL_SetRenderDrawColor(self.renderer,0x10,0x10,0x10,0xE0);
        SDL2.SDL_RenderClear(self.renderer);
        SDL2.SDL_SetRenderDrawColor(self.renderer,0xe0,0xe0,0xe0,0xf0);

    else
        View.Render(self);
    end
    if(self.texts)then
        local x,y = 0,0;
        if(self.drawPos)then
            --设置源的绘制地址
            if(self.drawPos.y<0)then
                --回拉效果 + 10
                self.drawPos.y = self.drawPos.y + 10;

            end
            y = y - self.drawPos.y;

        end
        local font = self.textFont;
        for k,v in ipairs(self.texts)do
            --已经绘制的文本,不等于
            if(v.Render==nil or v.drawd==nil or v.drawd.text ~=v.text)then
                if(v.drawd==nil)then v.drawd = {}; end;
                v.drawd.text = v.text;
                --
                local tfont = v.font;
                if(tfont==nil)then
                    tfont = font;
                end
                local surface = Text_CreateSurface(v.text,tfont);
                local texture = SDL2.SDL_CreateTextureFromSurface(self.renderer,surface);
                v.w,v.h = surface.w,surface.h;
                v.x,v.y = x,y;
                y = y + v.h;
                v.renderer = self.renderer;
                v.texture = ffi.gc(texture,SDL2.SDL_DestroyTexture);
                v.Render = function(self)
                    local rect = rectBuffer;
                    rect[0].x = self.x;
                    rect[0].y = self.y;
                    rect[0].w = self.w;
                    rect[0].h = self.h;
                    SDL2.SDL_RenderCopy(self.renderer,v.texture,nil,rect);
                    
                end
            else
                v.y = y;
                y = y + v.h;
            end

            


            v:Render();
            --如果被选中
            if(self.selectItem==v)then
                SDL2.SDL_SetRenderDrawColor(self.renderer,0x10,0x10,0x10,0x90);
                local rect = rectBuffer+0;
                rect.x = v.x;
                rect.y = v.y;
                rect.w = self.w;
                rect.h = v.h;
                SDL2.SDL_RenderFillRect(self.renderer,rect);
                SDL2.SDL_SetRenderDrawColor(self.renderer,0xe0,0xe0,0xe0,0xf0);
            end
            SDL2.SDL_RenderDrawLine(self.renderer,0,v.y,2000,v.y);
        end

        --如果拉到底部
        if(y<self.y+self.h-20)then
            if(self.drawPos)then
                --回拉效果 - 10
                self.drawPos.y = self.drawPos.y - 10;
            end
        end

    end
    if(self.texture)then
        SDL2.SDL_SetRenderTarget(self.renderer,target);
        View.Render(self);
    end
end

return {
    ListView = ListView,
    TextListView = TextListView,
}

